package com.xwintop.xJavaFxTool.services.littleTools;

import com.xwintop.xJavaFxTool.controller.littleTools.ImageToolController;
import com.xwintop.xcore.javafx.FxApp;
import com.xwintop.xcore.javafx.dialog.FxProgressDialog;
import com.xwintop.xcore.javafx.dialog.ProgressTask;
import com.xwintop.xcore.util.FileUtil;
import com.xwintop.xcore.util.javafx.TooltipUtil;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import javafx.collections.ObservableList;
import javax.imageio.ImageIO;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang.StringUtils;

/**
 * ImageToolService
 *
 * @author xufeng
 * @author yiding.he@gmail.com
 * @since 2017/12/28 0028 23:28
 */
@Getter
@Setter
@Slf4j
public class ImageToolService {

    private ImageToolController imageToolController;

    public void imageCompressionAction(boolean isPreview) throws IOException {

        int width = imageToolController.getScaleWidthSpinner().getValue();
        int height = imageToolController.getScaleHeightSpinner().getValue();
        String suffixName = imageToolController.getSuffixNameTextField().getText();
        String formatString = imageToolController.getFormatChoiceBox().getValue();
        ObservableList<ImageInfo> imageInfos = imageToolController.getTableData();

        FxProgressDialog fxProgressDialog = FxProgressDialog.create(FxApp.primaryStage, new ProgressTask() {
            @Override
            protected void execute() throws Exception {
                int total = imageInfos.size();
                for (int i = 0; i < imageInfos.size(); i++) {
                    ImageInfo imageInfo = imageInfos.get(i);
                    processImageInfo(isPreview, width, height, suffixName, formatString, imageInfo);
                    updateProgress(i + 1, total);
                }
            }
        }, "正在处理图片...");

        fxProgressDialog.setShowAsPercentage(false);
        fxProgressDialog.show();
    }

    private void processImageInfo(
        boolean isPreview, int width, int height, String suffixName, String formatString, ImageInfo rowValue
    ) throws IOException {

        File file = new File(rowValue.getImageFilePath());
        String outputFileName = file.getName();
        Thumbnails.Builder<File> builder = Thumbnails.of(file);
        builder.outputQuality(imageToolController.getQualitySlider().getValue() / 100.0d);//压缩率
        if (!"原格式".equals(formatString)) {//修改格式
            builder.outputFormat(formatString);
            outputFileName = FileUtil.getFileName(file) + "." + formatString;
        }
        if (imageToolController.getIsResizeCheckBox().isSelected()) {//缩放大小
            if (imageToolController.getSizeTypeChoiceBoxStrings()[0]
                .equals(imageToolController.getSizeTypeChoiceBox().getValue())) {
                builder.size(width, height);
            } else if (imageToolController.getSizeTypeChoiceBoxStrings()[1]
                .equals(imageToolController.getSizeTypeChoiceBox().getValue())) {
                builder.scale(width / 100.0d, height / 100.0d);
            }
            if (!imageToolController.getKeepAspectRatioCheckBox().isSelected()) {
                builder.keepAspectRatio(false);
            }
        } else {
            builder.scale(1);
        }
        if (isPreview) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            builder.toOutputStream(byteArrayOutputStream);
            rowValue.setCompressedSize(byteArrayOutputStream.size());
        } else {
            if (imageToolController.getSameFolderAsInput().isSelected()) {//输出路径为原路径
                if (StringUtils.isEmpty(suffixName)) {
                    TooltipUtil.showToast("保存在同目录下需添加前缀名。");
                } else {
                    outputFileName =
                        outputFileName.split("\\.")[0] + suffixName + "." + outputFileName.split("\\.")[1];
                    builder.toFile(file.getParent() + "/" + outputFileName);
                }
            } else {
                String outputPath = imageToolController.getOutputFolderTextField().getText();
                if (StringUtils.isEmpty(outputPath)) {
                    TooltipUtil.showToast("请选择需要保存的路径。");
                } else {
                    builder.toFile(outputPath + "/" + outputFileName);
                }
            }
        }
    }

    public BufferedImage getThumbnailPreview(String fullPath) {

        int width = imageToolController.getScaleWidthSpinner().getValue();
        int height = imageToolController.getScaleHeightSpinner().getValue();
        File file = new File(fullPath);

        double quality = imageToolController.getQualitySlider().getValue();

        Thumbnails.Builder<File> builder = Thumbnails.of(file);
        if (quality > 0) {
            builder.outputQuality(quality / 100.0d);//压缩率
        }

        if (imageToolController.getFormatChoiceBox().getSelectionModel().getSelectedIndex() > 0) {
            builder.outputFormat(imageToolController.getFormatChoiceBox().getValue());
        }

        String[] sizeTypes = imageToolController.getSizeTypeChoiceBoxStrings();
        String sizeType = imageToolController.getSizeTypeChoiceBox().getValue();

        if (imageToolController.getIsResizeCheckBox().isSelected()) {
            if (sizeTypes[0].equals(sizeType)) {
                builder.size(width, height);
            } else if (sizeTypes[1].equals(sizeType)) {
                builder.scale(width / 100.0d, height / 100.0d);
            }
            if (!imageToolController.getKeepAspectRatioCheckBox().isSelected()) {
                builder.keepAspectRatio(false);
            }
        } else {
            builder.scale(1);
        }

        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            builder.toOutputStream(bos);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            return ImageIO.read(bis);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public ImageToolService(ImageToolController imageToolController) {
        this.imageToolController = imageToolController;
    }
}
